package com.jackstraw.jack_base.datasource.common.config;

import com.jackstraw.jack_base.datasource.common.entity.AbstractPropertiesEntity;
import com.jackstraw.jack_base.datasource.common.entity.AbstractTemplate;
import com.jackstraw.jack_base.datasource.common.entity.DataSourceRouting;
import com.jackstraw.jack_base.datasource.common.entity.DataSourceTemplateCut;
import com.jackstraw.jack_base.datasource.common.entity.Properties;
import com.jackstraw.jack_base.datasource.common.factory.DataSourceBuildFactory;
import com.jackstraw.jack_base.util.EnvironmentUtil;
import com.jackstraw.jack_base.util.SpringUtil;
import com.jackstraw.jack_base.util.entity.BaseEntity;
import com.jackstraw.jack_base.util.tenant.entity.Tenant;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.Ordered;
import org.springframework.core.env.Environment;


@ConditionalOnClass({Tenant.class})
public abstract class DataSourceConfiguration<DSR extends DataSourceRouting<PE, T, P, DSR>,
        PE extends AbstractPropertiesEntity<PE>,
        T extends AbstractTemplate<T, PE>,
        DBF extends DataSourceBuildFactory<T, PE>,
        DTC extends DataSourceTemplateCut<T, PE>,
        P extends Properties<PE>,
        DC extends DataSourceConfiguration<DSR, PE, T, DBF, DTC, P, DC>> extends BaseEntity<DC> implements Ordered {

    private ApplicationContext applicationContext;

    private GenericApplicationContext genericApplicationContext;

    private Environment environment;


    public ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    public GenericApplicationContext getGenericApplicationContext() {
        return genericApplicationContext;
    }

    public Environment getEnvironment() {
        return environment;
    }

    public DataSourceConfiguration(ApplicationContext applicationContext, Environment environment) {
        this.applicationContext = applicationContext;
        this.genericApplicationContext = (GenericApplicationContext) applicationContext;
        this.environment = environment;
        SpringUtil.setApplicationContextJack(applicationContext);
        EnvironmentUtil.setEnvironmentJack(environment);
    }


    /**
     * 注入配置文件的方法
     *
     * @return
     */
    public abstract P properties();


    /**
     * Template工厂类
     *
     * @return
     */
    public abstract DBF dataSourceBuildFactory();

    /**
     * Template实现切面类
     *
     * @return
     */
    public abstract DTC dataSourceTemplateCut(DBF dataSourceBuildFactory);

    /**
     * 路由类
     *
     * @return
     */
    public abstract DSR routing();


    @Override
    public int getOrder() {
        return -1;
    }

}
